/**
 * Implementing fade effects on a DOM elements
 * 
 * @author  Mykhailo Stadnyk <mikhus@gmail.com>
 * @version $Rev$
 */
Jsl.extendDom( (function() {

	var

	_step = 5,

	_duration = 1000,

	C = Jsl.Collection,

	_fade = function( level, callback) {
		var styles = {
			opacity      : level,
			MozOpacity   : level,
			KhtmlOpacity : level,
			filter       : "alpha(opacity=" + (level * 100) + ");"
		};
		for (var prop in styles) {
			try {
				this.style[prop] = styles[prop];
			} catch (e) {
				continue;
			}
		};
		callback && callback.call( this); 
	};

	return {

	fadeIn  : function( duration, callback) {
		C.$populate();
		var duration = duration || _duration;
		for (i = 0; i <= 100; i += _step) {
			this.fadeInTimeout = setTimeout( 
				_fade.bind( this, i / 100, (i == 100 ? callback : null)),
				parseInt( i / 100 * duration)
			);
			try { if (i == 100) delete this.fadeInTimeout; } catch(err) {};
		}
		return this;
	},

	fadeOut : function( duration, callback) {
		C.$populate();
		var duration = duration || _duration;
		for (i = 0; i <= 100; i += _step) {
			this.fadeOutTimeout = setTimeout(
				_fade.bind( this, (1 - i / 100), (i == 100 ? callback : null)),
				parseInt( i / 100 * duration)
			);
			try { if (i == 100) delete this.fadeOutTimeout; } catch(err) {};
		}
		return this;
	},

	fadeUn : function() {
		this.fadeInTimeout && clearTimeout( this.fadeInTimeout);
		this.fadeOutTimeout && clearTimeout( this.fadeOutTimeout);
		delete this.fadeInTimeout;
		delete this.fadeOutTimeout;
		_fade.call( this, 1);
		return this;
	},

	fadeLoop : function( duration, len) {
		C.$populate();
		var
			duration = duration || _duration,
			self = this,
			cnt = 0
		;
		this.fadeUn();
		function _out() {
			if (len && (cnt >= len)) {
				return self.fadeUn();
			}
			self.fadeOut( duration, _in);
		};
		function _in() {
			self.fadeIn( duration, _out);
			if (len) {
				cnt++;
			}
		};
		_out();
		return this;
	}
}})());
